use std::{borrow::Cow, thread};

use axum::{http::{header, HeaderValue, StatusCode, Uri}, response::{IntoResponse, Response}, Router};
use rust_embed::Embed;
use tokio::net::TcpListener;

use crate::{error::AppErr, utils::global_rt};




pub fn init() {
    thread::spawn(|| {
        global_rt().block_on(server_run());
    });
}

async fn serve_impl() -> Result<(), AppErr> {
    let app = Router::new()
        .fallback(static_handler)
    ;

    let ln = TcpListener::bind("[::]:8080").await?;
    axum::serve(ln, app).await?;
    
    Ok(())
}


#[derive(Embed)]
#[folder = "../../web/test_app/dist"]
struct WebAsset;

async fn static_handler(uri: Uri) -> Response {
    let path = uri.path().trim_start_matches("/web/");
    
    if let Some(s) =  WebAsset::get(path) {
        let mut resp = s.data.into_response();
        let ct = HeaderValue::from_str(s.metadata.mimetype());
        if let Ok(ct) = ct {
            resp.headers_mut().insert(header::CONTENT_TYPE, ct);
        }
        return resp;
    }

    (StatusCode::NOT_FOUND, "404 Not Found").into_response()
}

async fn server_run() {
    let ret = serve_impl().await;
    if let Err(e) = ret {
        log::error!("server err:{}", e);
    }
}




